﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Globalization;
using System.Windows.Forms;

namespace Clock.Digtis
{
    public enum SevenSegmentClockStyle
    {
        DateOnly, // 只显示日期

        TimeOnly, // 只显示时间

        DateAndTime //显示日期和时间
    }

    public partial class SevenSegmentClock : UserControl
    {
        private Color clockColor = Color.Black;
        private SevenSegmentClockStyle clockStyle = SevenSegmentClockStyle.DateAndTime;
        private Graphics g;

        //是否绘制阴影（即残影），以摸拟真似的LED时钟
        private bool isDrawShadow = true;
        private Bitmap mBitmap;
        private readonly Timer timer;
        public DateTime dateTime;

        public SevenSegmentClock()
        {
            //使用双缓冲，支持透明绘制
            SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint
                     | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true);
            UpdateStyles();
            timer = new Timer();
            timer.Tick += TimerOnTick;
            timer.Interval = 1000;
            timer.Enabled = true;
            Init();
        }

        public bool IsDrawShadow
        {
            get { return isDrawShadow; }
            set
            {
                isDrawShadow = value;
                Invalidate();
            }
        }

        //LED文字的颜色
        public Color ClockColor
        {
            get { return clockColor; }
            set
            {
                clockColor = value;
                Invalidate();
            }
        }

        public SevenSegmentClockStyle SevenSegmentClockStyle
        {
            get { return clockStyle; }
            set
            {
                clockStyle = value;
                Invalidate();
            }
        }

        public int ClockStringWidth { get; private set; }

        public int ClockStringHeight { get; private set; }

        //初始化
        private void Init()
        {
            dateTime = DateTime.Now;
            mBitmap = new Bitmap(Width, Height);

            g = Graphics.FromImage(mBitmap);
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

            //g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            //g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
        }

        private void TimerOnTick(object obj, EventArgs ea)
        {
            DateTime dtNow = DateTime.Now;
            dtNow = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second);
            if (dtNow == dateTime) return;
            dateTime = dtNow;
            Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            mBitmap = DrawClock();
            Graphics gg = e.Graphics;
            gg.CompositingQuality = CompositingQuality.HighQuality;
            gg.DrawImageUnscaled(mBitmap, 0, 0);
        }

        public Bitmap DrawClock()
        {
            return DrawClock(ClientRectangle);
        }

        protected override void OnResize(EventArgs e)
        {
            Init();
            Refresh();
            base.OnResize(e);
        }


        //绘制时钟
        public Bitmap DrawClock(Rectangle destRect)
        {
            mBitmap = new Bitmap(destRect.Width, destRect.Height);

            Graphics grfx = Graphics.FromImage(mBitmap);
            //设置绘图面板的绘制质量等

            grfx.CompositingQuality = CompositingQuality.HighQuality;
            grfx.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            grfx.SmoothingMode = SmoothingMode.HighQuality;

            var ssd = new SevenSegmentDisplay(grfx);
            ssd.IsDrawShadow = isDrawShadow;
            GraphicsState gs = grfx.Save();
            grfx.TranslateTransform(destRect.X, destRect.Y);
            string strTime = string.Empty;
            if (clockStyle == SevenSegmentClockStyle.TimeOnly)
            {
                strTime = dateTime.ToString("T", DateTimeFormatInfo.InvariantInfo);
            }
            else if (clockStyle == SevenSegmentClockStyle.DateOnly)
            {
                //设置日期格式
                strTime = dateTime.ToString("yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo);
            }
            else
            {
                strTime = dateTime.ToString("yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo) + " " +
                          dateTime.ToString("T", DateTimeFormatInfo.InvariantInfo);
            }

            SizeF sizef = ssd.MeasureString(strTime, Font);
            float fScale = Math.Min(destRect.Width/sizef.Width, destRect.Height/sizef.Height);
            var font = new Font(Font.FontFamily, fScale*Font.SizeInPoints);

            sizef = ssd.MeasureString(strTime, font);
            ClockStringWidth = (int) sizef.Width;
            ClockStringHeight = (int) sizef.Height;

            ssd.DrawString(strTime, font, new SolidBrush(clockColor),
                           (destRect.Width - sizef.Width)/2,
                           (destRect.Height - sizef.Height)/2);
            grfx.Restore(gs);
            return mBitmap;
        }
    }
}